package com.UdpRecieve.secret.service.impl;


import com.UdpRecieve.domain.FileOption;
import com.UdpRecieve.domain.FilePigeonhole;
import com.UdpRecieve.mapper.FileOptionMapper;
import com.UdpRecieve.mapper.FilePigeonholeMapper;
import com.UdpRecieve.secret.domain.SecretLableResult;
import com.UdpRecieve.secret.log.BianjieLogUtils;
import com.UdpRecieve.secret.log.BussinessUtils;
import com.UdpRecieve.secret.service.SecretBusinessLogicInterface;
import com.UdpRecieve.tool.*;
import com.UdpRecieve.utils.FileUtiles;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 无密标-外网-文件归档类
 * 1.非秘的文件名就是文件名
 */
public class SecretBusinessLogic_FM_618 implements SecretBusinessLogicInterface {
    FileOptionMapper fileOptionMapper = SpringUtils.getBean(FileOptionMapper.class);
    FilePigeonholeMapper filePigeonholeMapper = SpringUtils.getBean(FilePigeonholeMapper.class);
    private BussinessUtils bussinessUtils = new BussinessUtils();
    private String ZipFileTemp = Global.getConfig("unCompressionFileName");//解压中间文件夹
    private String copyPath = null;
    private String saveRoot = null;
    private String saveSingle = null;
    /**
     * 明文文件传输流程
     *
     * @param filePigeonhole
     */
    public void saveFile(FilePigeonhole filePigeonhole, String resultSave) {
        SecretLableResult secretLableResult = new SecretLableResult();
        Date now = new Date();//当前时间
        //TODO 如果落地没成功记录日志
        if (!resultSave.equals("成功")) {//没成功,存储日志并发送
            System.out.println("-----------------------文件落地失败-------------------!");
            secretLableResult.setErrorMsg("文件落地失败");
            //存储业务日志-归档
            bussinessUtils.filePigeonholeLogSave618FM(filePigeonhole, secretLableResult, now);
            //发送日志给大边界
            filePigeonhole.setFileName(null);
            BianjieLogUtils.sendFileContentForBigBoundaryFM(filePigeonhole, secretLableResult);
            return;
        } else {
            secretLableResult.setSave_result(true);
        }

        //获取配置项
        List<FileOption> fileOptions = fileOptionMapper.selectFileOptionList(null);
        //获取文件落地路径
        saveRoot = fileOptions.get(0).getFileSaveRoot();
        copyPath = fileOptions.get(0).getIllegalPath();
        //获取单导根路径
        saveSingle = fileOptions.get(0).getSingleChannelPath();

        //判断是否压缩包
        if ("zip".equals(filePigeonhole.getFileName().split("\\.")[1])) {
            try {
                zipProcess(filePigeonhole, now, secretLableResult);
            } catch (Exception e) {
                System.out.println("解压文件:" + filePigeonhole.getFileName() + "失败!");
                e.printStackTrace();
                return;
            }
        } else {
            String fileName = filePigeonhole.getFileNames().get(0);
            filePigeonhole.setFileName(fileName);
            filePigeonhole.setFileType(fileName.split("\\.")[1]);
            noZipProcess(filePigeonhole, saveSingle, now, secretLableResult,null);
        }
    }


    /**
     * 压缩包流程
     *
     * @param filePigeonhole
     * @throws Exception
     */
    public void zipProcess(FilePigeonhole filePigeonhole, Date now, SecretLableResult secretLableResult) throws Exception {

        //文件全路径
        String zipInputFilePath = saveRoot + File.separator + filePigeonhole.getFileName();
        String uuid = UUID.randomUUID().toString();
        String zipOutFilePath = saveRoot + File.separator + uuid;
        //解压
        FileZip.zipUncompress(zipInputFilePath, zipOutFilePath);
        File fileOutFilePath = new File(zipOutFilePath);


        for (File f : fileOutFilePath.listFiles()) {
            if (f.isDirectory()) {//文件夹
                List<String> fileNames = new ArrayList<>();
                int count = FileUtiles.getFileNames(fileNames, f).size();
                //TODO 对文件夹重名
                //重置接收人
                String getNameZip = filePigeonhole.getGetName();
                //把接受方中多级的用-连接,以便后边拼接文件夹名称用
                if (getNameZip.contains("\\")) {
                    getNameZip = getNameZip.replaceAll("\\\\", "-");
                } else if (getNameZip.contains("/")) {
                    getNameZip = getNameZip.replaceAll("/", "-");
                }
                //重置解压路径（文件名<原>_接收方1级-接收方2级_文件数量）
                String fileZipPATH = f.getParent() + File.separator + f.getName().split("_")[1] + "_" + getNameZip + "_" + count;
                //重命名
                long startTime = System.currentTimeMillis();
                while (!f.renameTo(new File(fileZipPATH))) {
                    long endTime = System.currentTimeMillis();
                    if ((endTime - startTime) > 100000) {
                        break;
                    }
                }
                decompression(f.getPath(), filePigeonhole, secretLableResult, uuid);
            } else {
                filePigeonhole.setFileType(f.getName().split("\\.")[1]);
                filePigeonhole.setFileName(f.getName());
                filePigeonhole.setFilePath(f.getPath());
                noZipProcess(filePigeonhole, saveSingle, new Date(), secretLableResult,uuid);
            }
        }
        //删除压缩包文件
        FileUtil.deleteFile(zipInputFilePath);
    }


    private void decompression(String fileNameP, FilePigeonhole filePigeonhole, SecretLableResult secretLableResult, String uuid) {

        File file = new File(fileNameP);
        if (!file.exists()) {
            System.out.println("需要解标的文件夹不存在!" + file.getPath());
        }
        File[] fileNameList = file.listFiles();
        //遍历文件夹,并验标+解标
        for (File f : fileNameList) {
            if (!f.isDirectory()) {//文件
                //重置文件属性
                FilePigeonhole fp = filePigeonhole;
                fp.setFileName(f.getName());//文件名
                fp.setFileType(f.getName().substring(f.getName().lastIndexOf(".")));//.后缀
                fp.setFilePath(f.getPath());//文件全路径

                noZipProcess02(filePigeonhole, new Date(), secretLableResult);
            } else {//文件夹
                //递归
                decompression(f.getPath(), filePigeonhole, secretLableResult, uuid);
            }
        }

    }


    /**
     * 非压缩包文件流程
     *
     * @param filePigeonhole
     */
    public void noZipProcess02(FilePigeonhole filePigeonhole, Date now, SecretLableResult secretLableResult) {
        //获取配置项
        List<FileOption> fileOptions = fileOptionMapper.selectFileOptionList(null);
        //获取文件落地路径
        String saveRoot = fileOptions.get(0).getFileSaveRoot();
        //获取单导根路径
        String saveSingle = fileOptions.get(0).getSingleChannelPath();
        //TODO 获取输入输出路径
        String in_put_path = filePigeonhole.getFilePath();
        String out = saveSingle + File.separator + ZipFileTemp + File.separator + filePigeonhole.getGetName() + File.separator;
        String out_put_path = in_put_path.replaceAll(saveRoot, out);
        File f = new File(in_put_path);
        try {
            filePigeonhole.setMd5CheckNum(MD5FileUtils.getMD5(f));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //TODO 保证输出目录存在
        File file = new File(out_put_path);
        File filePath = new File(file.getParent());
        if (!filePath.exists()) {
            filePath.mkdirs();
        }
        //TODO 移动文件到单向导入系统目录下
        try {
            Files.move(Paths.get(in_put_path), Paths.get(out_put_path), StandardCopyOption.REPLACE_EXISTING);
            secretLableResult.setCopy_single(true);
        } catch (IOException e) {
            System.out.println("文件移动到单导目录失败!");
            e.printStackTrace();
            //存储移动失败日志
            bussinessUtils.filePigeonholeLogSave618FM(filePigeonhole, secretLableResult, now);
            return;
        }
        //TODO 存储和发送日志
        //发送总日志给大边界
        BianjieLogUtils.sendFileContentForBigBoundaryFM(filePigeonhole, secretLableResult);
        bussinessUtils.filePigeonholeLogSave618FM(filePigeonhole, secretLableResult, now);
        //封装归档对象
        filePigeonhole = BussinessUtils.installationF(filePigeonhole, null, null, now);
        //存储归档对象
        filePigeonholeMapper.insertFilePigeonhole(filePigeonhole);

    }

    /**
     * 非压缩包文件流程
     *
     * @param filePigeonhole
     * @param saveSingle     单导根路径
     */
    public void noZipProcess(FilePigeonhole filePigeonhole, String saveSingle, Date now, SecretLableResult secretLableResult,String uuid) {

        //TODO 获取输入输出路径
        String in_put_path = filePigeonhole.getFilePath();
        String out_put_path = saveSingle + File.separator +
                filePigeonhole.getGetName() + File.separator + filePigeonhole.getFileName();
        File f = new File(in_put_path);
        try {
            filePigeonhole.setMd5CheckNum(MD5FileUtils.getMD5(f));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //TODO 保证输出目录存在
        File file = new File(out_put_path);
        File filePath = new File(file.getParent());
        if (!filePath.exists()) {
            filePath.mkdirs();
        }
        //TODO 移动文件到单向导入系统目录下
        try {
            //备份
            String copyP = in_put_path.replace(saveRoot,copyPath);
            copyP = copyP.replace(uuid,filePigeonhole.getGetName());
            File file1 = new File(copyP);
            File fp = new File(file1.getParent());
            if (!fp.exists()){
                fp.mkdirs();
            }
            Files.copy(Paths.get(in_put_path),Paths.get(copyP), StandardCopyOption.REPLACE_EXISTING);
            Files.move(Paths.get(in_put_path), Paths.get(out_put_path), StandardCopyOption.REPLACE_EXISTING);
            secretLableResult.setCopy_single(true);
        } catch (IOException e) {
            System.out.println("文件移动到单导目录失败!");
            e.printStackTrace();
            //存储移动失败日志
            bussinessUtils.filePigeonholeLogSave618FM(filePigeonhole, secretLableResult, now);
            return;
        }
        //TODO 存储和发送日志
        //发送总日志给大边界
        BianjieLogUtils.sendFileContentForBigBoundaryFM(filePigeonhole, secretLableResult);
        bussinessUtils.filePigeonholeLogSave618FM(filePigeonhole, secretLableResult, now);
        //封装归档对象
        filePigeonhole = BussinessUtils.installationF(filePigeonhole, null, null, now);
        //存储归档对象
        filePigeonholeMapper.insertFilePigeonhole(filePigeonhole);

    }

}
